<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 18-8-16
 * Time: 下午1:57
 */

namespace appapi\behaviors;


use common\components\tools\ArrayHelper;
use common\members\wodrow\tools\Model;
use common\models\db\EquipmentUser;
use common\models\db\User;
use common\rewrite\deepziyu\yii_fast_api\ApiException;
use yii\base\ActionFilter;

class EquipmentUserAuthCheck extends ActionFilter
{
    /**
     * @param \yii\base\Action $action
     * @return bool
     * @throws ApiException
     * @throws \yii\base\Exception
     */
    public function beforeAction($action)
    {
        if (!\Yii::$app->equipmentInfo->equipment){
            throw new ApiException(201808161410, '设备异常');
        }
        $equipment = \Yii::$app->equipmentInfo->equipment;
        $params = ArrayHelper::merge(\Yii::$app->request->get(), \Yii::$app->request->post());
//        \Yii::$app->monolog->getLogger('main')->info($action->controller->route, $params);
        if (!isset($params['token'])) {
            throw new ApiException(201808161402, '请求必须有设备认证口令');
        }
        if (strlen($params['token'])!=50) {
            throw new ApiException(201808161403, '设备认证口令长度错误');
        }
        if (YII_ENV == 'prod'){
            if (!isset($params['timestamp'])) {
                throw new ApiException(201808161406, '请求必须有当前操作时间戳');
            }
            if (strlen($params['timestamp'])!=10) {
                throw new ApiException(201808161407, '时间戳长度必须为10位秒数');
            }
            if (abs(substr($params['timestamp'], 0, 10) - Yii_BT_TIME) > 600){
                throw new ApiException(201808161408, '操作超时或时间异常，请检查设备时间');
            }
            if (!isset($params['nonce'])) {
                throw new ApiException(201808161409, '请求必须设置随机数');
            }
            if (strlen($params['nonce'])<3) {
                throw new ApiException(201808161411, '随机数必须4位以上');
            }
            $tmp_nonces = is_array(\Yii::$app->cache->get($equipment->uuid.'_nonce_'.$params['token']))?\Yii::$app->cache->get($equipment->uuid.'_nonce_'.$params['token']):[];
            if (!in_array($params['nonce'], $tmp_nonces)){
                $tmp_nonces[] = $params['nonce'];
                \Yii::$app->cache->set($equipment->uuid.'_nonce_'.$params['token'], $tmp_nonces, 3600);
            }else{
                throw new ApiException(201808161412, '请求随机数重复');
            }
            if (!isset($params['sign'])) {
                throw new ApiException(201808161404, '请求必须有请求签名');
            }
            if (strlen($params['sign'])!=32) {
                throw new ApiException(201808161405, '请求签名长度错误');
            }
            $e_user = EquipmentUser::findOne(['equipment_id' => $equipment->id, 'token' => $params['token']]);
            if (!$e_user){
                throw new ApiException(201808161455, "没有找到设备用户,请重新登陆");
            }
            if ($e_user->user->status != User::STATUS_ACTIVE){
                throw new ApiException(201808161456, "用户状态异常,你是否被禁了");
            }
            $p = $params;
            $p['key'] = $e_user->key;
            ksort($p);
            unset($p['sign']);
            $p_arr = [];
            foreach ($p as $k => $v) {
                $p_arr[] = $k."=".$v;
            }
            $p_str = ArrayHelper::arr2str($p_arr, '&');
            $_sign = md5($p_str);
            if ($_sign != $params['sign']){
                throw new ApiException(201808161457, "验签失败");
            }
        }else{
            $e_user = EquipmentUser::findOne(['equipment_id' => $equipment->id, 'token' => $params['token']]);
            if (!$e_user){
                throw new ApiException(201808161455, "没有找到设备用户,请重新登陆");
            }
            if ($e_user->user->status != User::STATUS_ACTIVE){
                throw new ApiException(201808161456, "用户状态异常,你是否被禁了");
            }
        }
        if (\Yii::$app->user->login($e_user->user)){
            \Yii::$app->equipmentInfo->setEquipmentUser($e_user);
        }
        \Yii::$app->equipmentInfo->equipmentOperateLog->for_equipment_user = $e_user->id;
        return parent::beforeAction($action);
    }

    /**
     * @param \yii\base\Action $action
     * @param mixed $result
     * @return mixed
     * @throws ApiException
     * @throws \yii\base\Exception
     */
    public function afterAction($action, $result)
    {
        $e_user = \Yii::$app->equipmentInfo->equipmentUser;
        $e_user->last_use_at = Yii_BT_TIME;
        if (!$e_user->save()){
            throw new ApiException(201808161457 ,"设备用户更新失败:".Model::getModelError($e_user));
        }
        return parent::afterAction($action, $result);
    }
}